require_dependency "search" 

class Feed < ActiveRecord::Base
  has_many :items, :dependent=>:destroy, :order=>"pubDate DESC"
  belongs_to :authority
  acts_as_taggable
  validates_uniqueness_of :site_url
  validates_presence_of :site_url
  validates_presence_of :title
  before_create :check_feed_exists
  #after_create :grab_items
  searches_on :description, :title
  #validates_format_of :email,
   #                   :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i,
   #                   :message => 'email must be valid'
  
  def check_feed_exists
    feed_url= link.length>0 ? link : site_url
    feed=FeedTools::Feed.open(feed_url) rescue nil
    if feed
      self.link=feed.href # make sure that a feed address is stored for each feed!
      self.site_url=feed.link if (feed.link rescue nil) # link is what the feed calls the site address
      if feed.items==[]
        errors.add_to_base("No Entries in this blog!  Please write something before adding it to Scotedublogs") 
        return false
      end
    else 
      errors.add_to_base("No feed was found at this address")
      return false
    end
  end
  
  def live_items
    self.items.select{|i| i.expired==0}
  end
  
  def grab_items
    feed=FeedTools::Feed.open(self.link)
    pubDate=feed.time if feed.time
    feed.entries.each do |item|
      rails_item=self.items.create(
                                   :title=>FeedTools::HtmlHelper.unescape_entities(item.title),
      :pubDate=>item.time,
      :description=>FeedTools::HtmlHelper.unescape_entities(item.description),
      :author=>item.author.name,
      :link=>item.link)
      item.categories.each do |cat|
        rails_cat=Category.find_or_create_by_name(cat.term)
        rails_cat.save
        rails_item.categories<<rails_cat
      end rescue nil
      rails_item.save
    end
  end
  
  def expire_items
    self.items.each do |i|
     if i.expired=0
       i.expired=1
       i.save
     end
    end
  end
  
  def feed_tool_feed
    FeedTools::Feed.open(self.link)
  end
  
  def feed_tool_items
    feed_tool_feed.items 
  end
  
  def Feed.filtered_feeds(tags, authority, combinetype, sortby, searchtext)
    if authority && authority !="" && tags && tags != [] 
      
       @tags=tags
        #then get an array of feeds for each tag into an array of arrays:
        @feeds_array=@tags.map{|t| Tag.find_by_name(t).tagged}
        #and finally do this...
        #This would do an intersection of each of these arrays
        if combinetype == "any"
          @tag_feeds=@feeds_array.inject{|sum,n| sum + n}.uniq
        else
          # If you wanted inclusive, you could just do
          @tag_feeds=@feeds_array.inject{|sum,n| sum & n}.uniq
        end
         @authority=Authority.find(authority)
         @authority_feeds= @authority.feeds 
        @feeds = (@authority_feeds & @tag_feeds).uniq
        
        
    elsif tags && tags != []
    
        @tags=tags
        #then get an array of feeds for each tag into an array of arrays:
        @feeds_array=@tags.map{|t| Tag.find_by_name(t).tagged}
        #and finally do this...
        #This would do an intersection of each of these arrays
        if combinetype == "any"
          @feeds=@feeds_array.inject{|sum,n| sum + n}.uniq
        else
          # If you wanted inclusive, you could just do
          @feeds=@feeds_array.inject{|sum,n| sum & n}.uniq
        end
    
    elsif authority && authority!=""
    
      @authority=Authority.find(authority)
      @feeds= @authority.feeds  
      

    
    else
    
        @feeds=Feed.find(:all, :order=>"title")
    
    end
    
      if searchtext != ""
        @searched_feeds = Feed.search searchtext, :case => :insensitive
        @feeds = (@feeds & @searched_feeds).uniq
      end
    

   case sortby
   when "ztoa"
     @feeds.reverse!
   when "recent"
     @feeds=@feeds.sort_by{|f| f.pubDate_from_items.to_i}.reverse
   when "oldest"
     @feeds=@feeds.sort_by{|f| f.pubDate_from_items.to_i}
   end    
   return @feeds
  end
  
  def Feed.items_from_filtered_feeds(tags, authority, combinetype, sortby, searchtext)
    if tags || authority || sortby ||searchtext
      items=[]  
      Feed.filtered_feeds(tags, authority, combinetype, sortby, searchtext).each do |feed|
        items=items+feed.live_items
      end
      return items.sort_by{|i| i.pubDate}.reverse[0..20]
    else
      return Item.find(:all, :order=>"pubDate DESC", :limit=>21)
    end
  end
  
  def pubDate_from_items
    items==[]? nil : items.first.pubDate
  end
  
  def generate_token(size=40)
    self.token = Digest::MD5.hexdigest("#{inspect}#{Time.now}").first(size)
    save
    token
  end
  
  def generate_password(length = 6)
    chars = ('a'..'z').to_a + ('A'..'Z').to_a + ('1'..'9').to_a - ['o', 'O', 'i', 'I']
    clear_password=Array.new(length) { chars[rand(chars.size)] }.join
    password=Digest::MD5.hexdigest(clear_password)
    clear_password
  end
 
  
end
